#ifndef HTTP_SERVER_H
#define HTTP_SERVER_H

#include "../../../tcp/code/utility/Noncopyable.h"
#include "../../../tcp/code/TcpServer.h"
#include "../../../tcp/code/utility/Logger.h"

// 让外部只包含当前.h即可
#include "./HttpServer.h"
#include "./HttpRequest.h"
#include "./HttpContext.h"
#include "./HttpResponse.h"

// HTTPS用到
#include "../middleware/MiddlewareChain.h"
#include "../router/Router.h"
// #include "../ssl/SslContext.h"
#include "../ssl/SslConnection.h"
#include "../session/SessionManager.h"

class HttpRequest;
class HttpResponse;

class HttpServer : Noncopyable
{
public:
    using HttpCallback = std::function<void(const HttpRequest &, HttpResponse *)>; // 请求不变响应变

    // 类似TcpServer的构造方法
    HttpServer(EventLoop *loop,
               const InetAddress &listenAddr,
               TcpServer::ListenOption listenOpt,
               const std::string &threadName);

    void setHttpCallback(const HttpCallback &cb)
    {
        this->httpCallback_ = std::move(cb);
    }

    void start();

    // HTTPS用到
    HttpServer(EventLoop *loop,
               const InetAddress &listenAddr,
               TcpServer::ListenOption listenOpt,
               const std::string &threadName,
               bool useSsl);

    // EventLoop *getLoop() const
    // {
    //     return &this->loop_;
    // }
    void setThreadNum(int threadNum)
    {
        this->tcpServer_.setThreadNum(threadNum);
    }

    // 注册路由的方法命名是为了给外部简洁使用
    // 注册静态路由
    void Get(const std::string &path, const Router::HandlerFunc &cb)
    {
        this->router_.registerHandlerFunc(HttpRequest::Method::Get, path, std::move(cb));
    }
    void Get(const std::string &path, Router::HandlerPtr handler)
    {
        this->router_.registerHandlerPtr(HttpRequest::Method::Get, path, handler);
    }

    void Post(const std::string &path, const Router::HandlerFunc &cb)
    {
        this->router_.registerHandlerFunc(HttpRequest::Method::Post, path, std::move(cb));
    }
    void Post(const std::string &path, Router::HandlerPtr handler)
    {
        this->router_.registerHandlerPtr(HttpRequest::Method::Post, path, handler);
    }

    // 注册动态路由
    void addRoute(HttpRequest::Method method, const std::string &path, const Router::HandlerFunc &cb)
    {
        this->router_.addRegexHandlerFunc(method, path, std::move(cb));
    }
    void addRoute(HttpRequest::Method method, const std::string &path, Router::HandlerPtr handler)
    {
        this->router_.addRegexHandlerPtr(method, path, handler);
    }

    // 会话管理器
    void setSessionManager(std::unique_ptr<SessionManager> sessionManager)
    {
        this->sessionManager_ = std::move(sessionManager);
    }
    SessionManager *getSessionManager() const
    {
        return this->sessionManager_.get();
    }

    // 中间件
    void addMiddleware(std::shared_ptr<Middleware> middleware)
    {
        this->middlewareChain_.addMiddleware(middleware);
    }

    // SSL
    void enableSSL(bool enableSsl)
    {
        this->useSsl_ = enableSsl;
    }
    void setSslConfig(const SslConfig &sslConfig);

private:
    // 静态不依赖对象，才能转为HttpCallback移动给成员变量
    static void defaultHttpCallback(const HttpRequest &request, HttpResponse *response);

    void onConnectionCallback(const TcpConnectionPtr &conn);
    void onReadWriteCallback(const TcpConnectionPtr &conn, Buffer *buffer, Timestamp receiveTime);
    void handleRequest(const TcpConnectionPtr &conn, const HttpRequest &request);

    TcpServer tcpServer_;
    HttpCallback httpCallback_;

    // HTTPS用到
    void handleRequest2(const HttpRequest &request, HttpResponse *response);
    void onConnectionCallback2(const TcpConnectionPtr &tcpConn);
    void onReadWriteCallback2(const TcpConnectionPtr &tcpConn, Buffer *buf, Timestamp receiveTime);

    bool useSsl_ = false;
    // EventLoop loop_;
    MiddlewareChain middlewareChain_;
    Router router_;
    std::unique_ptr<SslContext> sslCtx_;
    std::map<TcpConnectionPtr, std::unique_ptr<SslConnection>> tcpToSslConns_; // TcpConnectionPtr -> SslConnectionPtr
    std::unique_ptr<SessionManager> sessionManager_;
};

#endif // HTTP_SERVER_H